﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace WHControlLib.Controls

{
    //****************************说明**************************************
    // *******************进度条的进度通过 Value属性设置*******************
    //*****要想获得本进度条的当前进度的百分比值通过只读属性 Valuepercentage 获得*****

    public partial class WHProgressBar : UserControl
    {
        public WHProgressBar()
        {
            //设置双缓冲
            //设置双缓冲开启禁止背景擦拭
            SetStyle(
                     ControlStyles.OptimizedDoubleBuffer
                     | ControlStyles.ResizeRedraw
                     | ControlStyles.Selectable
                     | ControlStyles.AllPaintingInWmPaint
                     | ControlStyles.UserPaint
                     | ControlStyles.SupportsTransparentBackColor
                     , true
                    );

            ////背景定义为透明色   
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            BackColor = Color.Transparent;
            InitializeComponent();
        }

        //***************全局定义***************************
      public Rectangle MyRect = new Rectangle();
       public Rectangle ProgressTextRect = new Rectangle();
    public    string progessValueStr = "";

        //*************************************************
        #region  属性定义 

         protected int _valuepercentage;

        public int Valuepercentage
        {
            get =>  _valuepercentage; 
      
        }

        private int _value;
        [Category("A我的"), Description("当前的进度值，默认，0"), Browsable(true)]
        public int Value
        {
            get => _value;
            set { _value = value; Invalidate(); }
        }
        private int _minimum;
        [Category("A我的"), Description("进度的最小值值，默认，0，不能小于0"), Browsable(true)]
        public int Minimum
        {
            get => _minimum;
            set
            {
                if (value < 0)
                {
                    _minimum = 0;
                }
                else
                    _minimum = value; Invalidate();
            }
        }
        private int _maximum = 100;
        [Category("A我的"), Description("进度的最大值值，默认，100，不能小于0"), Browsable(true)]
        public int Maximum
        {
            get => _maximum;
            set
            {
                if (value < 0)
                {
                    _maximum = 0;
                }
                else
                    _maximum = value; Invalidate();
            }
        }
        private int _step=1;
        [Category("A我的"), Description("进度每次增加的数量，默认，10，不能小于0"), Browsable(true)]
        public int Step
        {
            get => _step;
            set
            {
                if (value < 0)
                {
                    value = 1;

                }
                else
                    _step = value;
            }
        }


        private bool _isShowBorder = true;
        [Category("A我的"), Description("是否显示控件外边框，默认，true"), Browsable(true)]
        public bool IsShowBorder
        {
            get => _isShowBorder;
            set { _isShowBorder = value; Invalidate(); }

        }


        private Color _unEnableColor = Color.Gray;
        [Category("A我的"), Description("当不可用时候的颜色，默认，灰色"), Browsable(true)]
        public Color UnEnableColor
        {
            get => _unEnableColor;
            set { _unEnableColor = value; Invalidate(); }
        }
        private Color _borderColor = Color.Blue;
        /// <summary>
        /// 边框颜色
        /// </summary>
        [Category("A我的"), Description("边框颜色"), Browsable(true)]
        public Color BorderColor
        {
            get => _borderColor;
            set { _borderColor = value; Invalidate(); }
        }

        private int _borderWidth = 2;
        [Category("A我的"), Description("边框的宽度，默认 2"), Browsable(true)]
        public int BorderWidth
        {
            get => _borderWidth;
            set { _borderWidth = value; Invalidate(); }
        }

        private Color _backgroundColor = Color.White;
        [Category("A我的"), Description("内部背景色的颜色，默认，白色"), Browsable(true)]
        public Color BackgroundColor
        {
            get => _backgroundColor;
            set { _backgroundColor = value; Invalidate(); }
        }

        private bool _isUseShadow=true;
        [Category("A我的"), Description("是否启用内部阴影，默认，启用"), Browsable(true)]
        public bool IsUseShadow
        {
            get => _isUseShadow;
            set  {
                _isUseShadow=value;
                Invalidate(); } 
        }

        private Color _insideShadowColor = Color.Gray;
        [Category("A我的"), Description("内部阴影的颜色，默认，灰色"), Browsable(true)]
        public Color InsideShadowColor
        {
            get => _insideShadowColor;
            set => _insideShadowColor = value;
        }


        private bool _isUseTwoColor=true  ;
          
        [Category("A我的"), Description("是否启用两种渐变色的颜色填充，可增加立体感，默认 是"), Browsable(true)]
        public bool IsUseTwoColor
        {
            get => _isUseTwoColor;
            set { _isUseTwoColor = value; Invalidate(); }
        }
        /// <summary>
        /// 第一种背景填充色
        /// </summary>
        private Color _firstFillcolor = Color.DarkOrange;
        [Category("A我的"), Description(" 第一种进度条填充色,默认 深橙色"), Browsable(true)]
        public Color FirstFillcolor
        {
            get => _firstFillcolor;
            set
            {
                _firstFillcolor = value;

                Invalidate();
            }
        }
        private Color _secondFillcolor = Color.PapayaWhip;
        [Category("A我的"), Description(" 第二种进度条填充色"), Browsable(true)]
        public Color SecondFillcolor
        {
            get => _secondFillcolor;
            set
            {
                _secondFillcolor = value;

                Invalidate();
            }
        }
        private int _progessbarBl=8;
        [Category("A我的"), Description(" 进度条形状与背景的间隔比例度，默认 8 分之一"), Browsable(true)]
        public int progessbarBl
        {
            get { return _progessbarBl; }
            set { _progessbarBl = value; Invalidate(); }
        }
        public enum FillColorDec
        {
            Vertical,
            Horizontal,
            LeftVH,
            RightVH

        }
        private FillColorDec _myFillColorDec = FillColorDec.Vertical;
        [Category("A我的"), Description("当启用渐变色的渐变色变化方向，默认，垂直方向"), Browsable(true)]
        public FillColorDec MyFillColorDec
        {
            get { return _myFillColorDec; }
            set { _myFillColorDec = value; Invalidate(); }
        }

        private bool _isShowText;
        [Category("A我的"), Description("是否在进度条上显示进度百分比，默认，false"), Browsable(true)]
        public bool IsShowText
        {
            get { return _isShowText; }
            set { _isShowText = value; Invalidate(); }
        }
        private Color _progessTextColor = Color.Black;
        [Category("A我的"), Description("进度条上文本的颜色，默认，黑色 "), Browsable(true)]
        public Color ProgessTextColor
        {
            get => _progessTextColor;
            set { _progessTextColor = value; Invalidate(); }
        }

        private Font _progessTextFont = new Font("宋体", 12);
        [Category("A我的"), Description("进度条上文字字体，默认，宋体不太理想，可换微软雅黑为了兼容xp默认 "), Browsable(true)]
        public Font ProgessTextFont
        {
            get => _progessTextFont;
            set { _progessTextFont = value; Invalidate(); }
        }
        private string _progessText="";
        [Category("A我的"), Description("进度条上文本，默认， "), Browsable(true)]
        public string ProgessText
        {
            get { return _progessText; }
            set { _progessText = value; }
        }

        public enum ProgressBarDec
        { LeftToRight,ButtomToTop,TopToButtom

        }

        private ProgressBarDec _myProgressBarDec=ProgressBarDec.LeftToRight;
        [Category("A我的"), Description("进度条的方向，默认，从左到右 "), Browsable(true)]
        public ProgressBarDec MyProgressBarDec
        {
            get { return _myProgressBarDec; }
            set { _myProgressBarDec = value; Invalidate(); }
        }


        #endregion
      public virtual  void BiforePainIni()
        {
        }
      void GetProgessBarDec(Graphics Myg)

        {
           

        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            BiforePainIni();

            Graphics Myg = e.Graphics;
            Myg.SmoothingMode = SmoothingMode.AntiAlias;
            Myg.CompositingQuality = CompositingQuality.HighQuality;
            Myg.InterpolationMode = InterpolationMode.HighQualityBicubic;
            //确定进度条的方向
            switch (MyProgressBarDec)
            {
                case ProgressBarDec.LeftToRight:
                    MyRect = ClientRectangle;
                    break;
                case ProgressBarDec.ButtomToTop:
                    MyRect.X = 0;
                    MyRect.Y = 0;
                    MyRect.Width = Height;
                    MyRect.Height = Width;
                    Myg.TranslateTransform(0, Height);
                    Myg.RotateTransform(270);
                    break;
                case ProgressBarDec.TopToButtom:

                    MyRect.X = 0;
                    MyRect.Y = 0;
                    MyRect.Width = Height;
                    MyRect.Height = Width;
                    Myg.TranslateTransform(Width, 0);
                    Myg.RotateTransform(90);
                    break;

                default:
                    MyRect = ClientRectangle;
                    break;
            }


            //画进度条的背景形状和填充
            DrawProgessInside(Myg, MyRect);

            //画填充进度条
            DrawValueProgess(Myg, MyRect);

            //画边框
            if (IsShowBorder)
            {
                 DrawProgessBorder(Myg, MyRect, BorderWidth);
            }
          
            //画出百分比文字
            if (IsShowText)
            {
                DrawProgessText(Myg, MyRect, progessValueStr);
            }
        }

       public virtual void DrawProgessInside(Graphics Myg, Rectangle myrect)

        {
            //根据是否有阴影填充控件内部颜色
            FillProgessInside(Myg, myrect);

        }

       public virtual void DrawValueProgess(Graphics Myg, Rectangle myrect)
        {
            Rectangle ValueRect = new Rectangle();
           //将比例字符串清空一下
            progessValueStr = "";
            string progessstr;
            GraphicsPath pValePath = GetProgessValueFillPath(myrect, Value, Maximum, Minimum, out ValueRect,out progessstr);
           //将两个输出参数重新赋值
            ProgressTextRect = ValueRect;
            progessValueStr = progessstr;


            if (pValePath != null)
            {
                if (IsUseTwoColor)
                {
                    switch (MyFillColorDec)
                    {
                        case FillColorDec.Vertical:
                            using (LinearGradientBrush PValueBrush = new LinearGradientBrush(ValueRect, FirstFillcolor, SecondFillcolor, LinearGradientMode.Vertical))
                            {

                                Myg.FillPath(PValueBrush, pValePath);
                            }
                            break;
                        case FillColorDec.Horizontal:
                            using (LinearGradientBrush PValueBrush = new LinearGradientBrush(ValueRect, FirstFillcolor, SecondFillcolor, LinearGradientMode.Horizontal))
                            {

                                Myg.FillPath(PValueBrush, pValePath);
                            }
                            break;
                        case FillColorDec.LeftVH:
                            using (LinearGradientBrush PValueBrush = new LinearGradientBrush(ValueRect, FirstFillcolor, SecondFillcolor, LinearGradientMode.ForwardDiagonal))
                            {

                                Myg.FillPath(PValueBrush, pValePath);
                            }
                            break;
                        case FillColorDec.RightVH:
                            using (LinearGradientBrush PValueBrush = new LinearGradientBrush(ValueRect, FirstFillcolor, SecondFillcolor, LinearGradientMode.BackwardDiagonal))
                            {

                                Myg.FillPath(PValueBrush, pValePath);
                            }
                            break;
                        default:
                              using (LinearGradientBrush PValueBrush = new LinearGradientBrush(ValueRect, FirstFillcolor, SecondFillcolor, LinearGradientMode.Vertical))
                    {

                        Myg.FillPath(PValueBrush, pValePath);
                    }  
                            break;
                    }

               

                }
                else
                {
                    using (SolidBrush PValueBrush = new SolidBrush(FirstFillcolor))
                    {

                        Myg.FillPath(PValueBrush, pValePath);
                    }
                }
            }
            //如果启用两种颜色填充进度


        }

        public virtual void FillProgessInside(Graphics Myg, Rectangle myRect)
        {
            int bwidth = 0;
            if (IsShowBorder)
            {
                bwidth = (int)BorderWidth / 2;
            }
            //int W = (int)myRect.Height / 2;
            //当背景启用阴影时候
            if (IsUseShadow)
            {
         
                int shadowH = myRect.Height / 2;

                //整体外形填充
                using (LinearGradientBrush backgroundBrush = new LinearGradientBrush(myRect, InsideShadowColor, BackgroundColor, LinearGradientMode.ForwardDiagonal))
                {
                    GraphicsPath backgroundPath = DrawHelper.GetTwoHalfCircleRect(myRect, bwidth);
                   
                    Myg.FillPath(backgroundBrush, backgroundPath);
                }

        

            }
            //当背景不启用阴影时候
            else
            {
                using (SolidBrush backgroundBrush = new SolidBrush(BackgroundColor))
                {
                    GraphicsPath backgroundPath = DrawHelper.GetTwoHalfCircleRect(myRect, bwidth);
                    Myg.FillPath(backgroundBrush, backgroundPath);
                }
            }

        }


        /// <summary>
        /// 获得当i前进度值对应的进度条路径
        /// </summary>
        /// <param name="myrect">控件范围的矩形</param>
        /// <param name="nowvalue">当前进度值</param>
        /// <param name="Maximum">最大值</param>
        /// <param name="Minimum">最小值</param>
        /// <param name="ValueRect">输出当前进度的画刷矩形</param>
        /// <returns></returns>
        public virtual  GraphicsPath GetProgessValueFillPath(Rectangle myrect, int nowvalue, int Maximum, int Minimum, out Rectangle ValueRect,out string pstr)
        {
            string PgStr = "";
            int borderWidth = 0;
            if (IsShowBorder)
            {
                borderWidth = (int)BorderWidth / 2;
            }

            int shadowH = myrect.Height / 2;
            int f = progessbarBl;
            Rectangle valueRect = new Rectangle();
            valueRect.X = myrect.X + (int)shadowH / f;
            valueRect.Y = myrect.X + (int)shadowH / f;
            //valueRect.Width = myrect.Width - shadowH / f * 2;
            valueRect.Height = myrect.Height - shadowH / f * 2;
            //计算 当前valu值代表的进度的矩形的宽度

            int longp = Maximum - Minimum;
            int valuep = nowvalue - Minimum;
            if (longp <= 0)
            {
                valueRect.Width = myrect.Width - shadowH / f * 2;
                    ValueRect = valueRect;
                PgStr = "0%";
                pstr = PgStr;
                //return DrawHelper.GetTwoHalfCircleRect(valueRect, borderWidth);
                return null;


            }
            else
            {
                if (valuep <=0)
                
                {valuep = 0;
                    ValueRect = valueRect;
                    PgStr = "0%";
                    pstr = PgStr;
                    _valuepercentage = 0;
                    return null; }
                else
                if (valuep>=longp)
                {
                    valueRect.Width = (int)(myrect.Width ) - shadowH / f * 2;
                    ValueRect = valueRect;
                    PgStr = "100%";
                    pstr = PgStr;
                    _valuepercentage = 100; 
                    return DrawHelper.GetTwoHalfCircleRect(valueRect, borderWidth);
                }
                else
                {   
                    float bl = Math.Abs( (float)valuep / longp);
                     valueRect.Width = (int) (myrect.Width * bl) - shadowH / f * 2 ;
                    if (valueRect.Width<1)
                    {
                        valueRect.Width = 1;

                    }
                      ValueRect = valueRect;
               
                    string s =(bl*100) .ToString("#0");
                    PgStr =s+ "%";
                    pstr = PgStr;
                    _valuepercentage = Convert.ToInt32(bl * 100);
                    return DrawHelper.GetTwoHalfCircleRect(valueRect, borderWidth);

                }
          
            }
        }


        public virtual void DrawProgessText( Graphics Myg, Rectangle myrect,string progessText)
        {
            //int borderWidth = 0;
            //if (IsShowBorder)
            //{
            //    borderWidth = (int)BorderWidth / 2;
            //}

            //int shadowH = myrect.Height / 2;
            //int f = progessbarBl;
            //Rectangle valueRect = new Rectangle();
            //valueRect.X = myrect.X + (int)shadowH / f;
            //valueRect.Y = myrect.X + (int)shadowH / f;
            ////valueRect.Width = myrect.Width - shadowH / f * 2;
            //valueRect.Height = myrect.Height - shadowH / f * 2;
           
            StringFormat sf = new StringFormat();
            sf.LineAlignment=StringAlignment.Center;
            sf.Alignment = StringAlignment.Far;

            Rectangle TextRect = new Rectangle();
            TextRect = ProgressTextRect;
            //////////当文字大于显示区域时候不显示文字
            SizeF textSize = Myg.MeasureString(progessText, ProgessTextFont);
            //int W= Math.Min((int)textSize.Height, TextRect.Height);
             if ((int)textSize.Width>TextRect.Width)
               {
                progessText = "";
                return;
                }
            using (SolidBrush textbrush=new SolidBrush(ProgessTextColor))
            {
                Myg.DrawString(progessText, ProgessTextFont, textbrush, TextRect, sf);
            }
        }

           public virtual void DrawProgessBorder(Graphics Myg,Rectangle myrect,int Bwidth)
        {
            using (Pen borderPen=new Pen(BorderColor,BorderWidth))
            {
                Myg.DrawPath(borderPen, DrawHelper.GetTwoHalfCircleRect(myrect, Bwidth));

            }


        }

        //////////////////////////////////////////////////////////////////////////
    }
}
